//1
//        2
//        3
//        4
//        5
//        6
//        7
//        8
//        9
//        10
//        11
//        12
//        13
//        14
//        15
//        16
//        17
//        18
//        19
//        20
//        21
//        22
//        23
//        24
//        25
//        26
//        27
//        28
//        29
//        30
//        31
//        32
//        33
//        34
//        35
//        36
//        37
//        38
//        39
//        40
//        41
//        42
//        43
//        44
//        45
//        46
//        47
//        48
//        49
//        50
//        51
//        52
//        53
//        54
//        55
//        56
//        57
//        58
//        59
//        60
//        61
//        62
//        63
//        64
//        65
//        66
//        67
//        68
//        69
//        70
//        71
//        72
//        73
//        74
//        75
//        76
//        77
//        78
//        79
//        80
//        81
//        82
//        83
//        84
//        85
//        86
//        87
//        88
//        89
//        90
//        91
//        92
//        93
//        94
//        95
//        96
//        97
//        98
//        99
//        100
//        101
//        102
//        103
//        104
//        105
//        106
//        107
//        108
//        109
//        110
//        111
//        112
//        113
//        114
//        115
//        116
//        117
//        118
//        119
//        120
//        121
//        122
//        123
//        124
//        125
//        126
//        127
//        128
//        129
//        130
//        131
//        132
//        133
//        134
//        135
//        136
//        137
//        138
//        139
//        140
//        141
//        142
//        143
//        144
//        145
//        146
//        147
//        148
//        149
//        150
//        151
//        152
//        153
//        154
//        155
//        156
//        157
//        158
//        159
//        160
//        161
//        162
//        163
//        164
//        165
//        166
//        167
//        168
//        169
//        170
//        171
//        package com.starcharge.iot.netty;
//
//import java.io.IOException;
//import java.util.Set;
//
//import org.apache.commons.lang.StringUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//import com.starcharge.iot.model.ParamInfo;
//import com.starcharge.iot.service.IL;
//import com.starcharge.iot.service.L0BService;
//import com.starcharge.iot.service.LogService;
//import com.starcharge.iot.utils.DigitalUtils;
//import com.starcharge.iot.utils.JSONUtilsEx;
//import com.starcharge.iot.utils.ProtocolUtils;
//import com.starcharge.iot.utils.SpringUtils;
//
//import io.netty.channel.ChannelDuplexHandler;
//import io.netty.channel.ChannelHandlerContext;
//import io.netty.channel.ChannelHandler.Sharable;
//
///**
// * 综合平台在超过10分钟未接收到企业平台的任何有效数据或心跳包的情况，主动断开与企业平台的TCP连接。<br>
// * 阿里云900秒内，无响应会断开SLB<br>
// *
// * @author TYOTANN
// */
//@Sharable
//public class SCServerHandler extends ChannelDuplexHandler {
//
//    private final static Logger logger = LoggerFactory.getLogger(SCServerHandler.class);
//
////	private static FastThreadLocal<Map<String,JSONObject>> LOCAL = new FastThreadLocal<Map<String,JSONObject>>() {
////		@Override
////		protected Map<String,JSONObject> initialValue() {
////			Map<String,JSONObject> map = Maps.newHashMap();
////			return map;
////		}
////	};
////
////	public static Object getLocalValue(String stubId,String key) {
////		if(StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(stubId)) {
////			if(LOCAL.get().get(stubId) != null) {
////				if(LOCAL.get().get(stubId).containsKey(key)) {
////					return LOCAL.get().get(stubId).get(key);
////				}
////			}
////		}
////		return null;
////	}
////
////	public static void setLOCAL(String stubId, String key,Object value) {
////		//桩编号和key不能为空
////		if(StringUtils.isEmpty(stubId) || StringUtils.isEmpty(key)) {
////			return;
////		}
////		//桩编号不存在
////		if(!LOCAL.get().containsKey(stubId)) {
////			//新建对象
////			JSONObject o = new JSONObject();
////			o.put(key, value);
////			//设置缓存
////			LOCAL.get().put(stubId, o);
////		} else {
////			//存在对象
////			if(LOCAL.get().get(stubId) != null) {
////				//存入local
////				LOCAL.get().get(stubId).put(key, value);
////			} else {
////				//对象为空
////				JSONObject o = new JSONObject();
////				//塞入对象
////				o.put(key, value);
////				LOCAL.get().put(stubId, o);
////			}
////		}
////	}
////
////	public static void clearAll() {
////		FastThreadLocal.removeAll();
////	}
////
////
////	public static void clearStubs(Set<String> stubIds) {
////		if(CollectionUtils.isEmpty(stubIds)) {
////			return;
////		}
////		for(String stubId : stubIds) {
////			clearStubs(stubId);
////		}
////	}
////
////
////	public static void clearStubs(String stubId) {
////		if(LOCAL.get().containsKey(stubId)) {
////			LOCAL.get().remove(stubId);
////			logger.info("当前线程ID:"+Thread.currentThread().getId()+"，桩编号："+stubId+" 进行清理local");
////		}
////	}
//
//    @Override
//    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//        if(ctx == null) {
//            return;
//        }
//        ParamInfo param = null;
//        // 解析出数据做循环
//        String hex = DigitalUtils.byte2hex((byte[]) msg);
//
//        LogService.info(null, "msg", null, "收到消息:" + hex);
//
//        String channelId = SChannelContext.getChannelId(ctx);
//
//        Set<String> hex_arr = ProtocolUtils.getEvenPackage(hex, channelId);
//
//        if (hex_arr.size() > 0) {
//
//            for (String hex_unit : hex_arr) {
//                try {
//                    // 解析数据
//                    param = ProtocolUtils.decode(hex_unit);
//
//                    // 在channel中注册桩编号
//                    if (param != null && StringUtils.isNotBlank(param.getStubId())) {
//                        // 先检查是否为空 || 或者没满足验证要求
//                        if (null == ctx || !SChannelContext.validateChannel(param, ctx)) {
//                            if (null != ctx && ctx.channel().isOpen()) {
//                                // 直接走0B失败
//                                L0BService il = (L0BService) SpringUtils.getBean("L0BService");
//                                if (il != null)
//                                    il.channel(ctx, param);
//                                LogService.info(param.getStubId(), "validate", null, "在黑名单或未通过认证");
//                            }
//                            return;
//                        }
//                    }
//                    if(param != null)
//                        LogService.info(param.getStubId(), param.getServiceName(), null, "[收到消息后业务]paramInfo:" + JSONUtilsEx.serialize(param));
//
//                    // 如果前处理无异常
//                    if (param != null && "00".equals(param.getErrCode())) {
//
//                        IL il = (IL) SpringUtils.getBean("L" + param.getServiceName() + "Service");
//
//                        if (il != null)
//                            il.sendMQ(ctx, param);
//                    }
//                } catch (ServiceException e) {
//                } catch (Throwable e) {
//
//                    LogService.error(null, "channelRead", null, "业务逻辑处理出现未预见异常:" + e.getMessage(), e);
//                }
//            }
//        }
//    }
//
//    @Override
//    public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception {
//
//        try {
//            if (!(e instanceof IOException)) {
//                LogService.error(null, "exceptionCaught", null, "出现未知异常:" + e.getMessage(), e);
//            }
//        } finally {
//            ctx.close();
//        }
//    }
//
//}
//
